package reporte;

import productosYPresentaciones.Producto;
import reporte.filtros.*;
import sucursal.Stock;

public class BuilderFiltroProducto {
	
	private Filtro<Producto> filtroproducto;
	
	/**
	 * Contructor del Builder.
	 * Sirve para instanciar los metodos static
	 * @param filtro
	 * Es el filtro del cual estara compuesto
	 */
	protected BuilderFiltroProducto(Filtro<Producto> filtro){
		this.filtroproducto = filtro;
	}
	
	/**
	 * Crea un constructor del filtro que siempre pasa todo 
	 * @return
	 * Un Builder que dejara pasar todos los productos.
	 */
	public static BuilderFiltroProducto filtroTrue(){
		return new BuilderFiltroProducto(new FiltroTrue<Producto>());
	}
	
	/**
	 * Crea un constructor del filtro que dejara pasar a los productos que esten
	 * por debajo del stock critico
	 * @param stock
	 * El stock que se toma como referencia
	 * @return
	 * Un Builder que dejara pasar a los productos que cumplan
	 * la condicion.
	 */
	public static BuilderFiltroProducto filtroPorDebajoDeStockCritico(Stock stock){
		return new BuilderFiltroProducto(new FiltroProductosPorDebajoDeStockCritico(stock));
	}
	

	/**
	 * Crea un constructor del filtro que dejara pasar a los productos que esten
	 * por debajo del stock minimo
	 * @param stock
	 * El stock que se toma como referencia
	 * @return
	 * Un Builder que dejara pasar a los productos que cumplan
	 * la condicion.
	 */
	public static BuilderFiltroProducto filtroPorDebajoDeStockMinimo(Stock stock){
		return new BuilderFiltroProducto(new FiltroProductosPorDebajoDeStockMinimo(stock));
	}
	
	/**
	 * Crea un constructor del filtro que niega la condicion del filtro
	 * @return
	 * Un Builder que nego la condicion del Builder anterior.
	 */
	public BuilderFiltroProducto neg(){
		return new BuilderFiltroProducto(new FiltroNot<Producto>
				(this.build()));
	}
	
	/**
	 * Crea un constructor del filtro que debe dejar pasar productos 
	 * que cumplan ambos constructores.
	 * @param builder
	 * El builder con el que se unira.
	 * @return
	 * Un Builder que hace un And entre las condiciones de los builders. 
	 */
	public BuilderFiltroProducto and(BuilderFiltroProducto builder){
		return new BuilderFiltroProducto(new FiltroAnd<Producto>
				(this.build(),builder.build()) );
	}
	
	/**
	 * Crea un constructor del filtro que debe dejar pasar productos 
	 * que cumplan algun constructor.
	 * @param builder
	 * El builder con el que se unira.
	 * @return
	 * Un Builder que hace un Or entre las condiciones de los builders. 
	 */
	public BuilderFiltroProducto or(BuilderFiltroProducto builder){
		return new BuilderFiltroProducto(new FiltroOr<Producto>
				(this.build(),builder.build()) );
	}
	
	/**
	 * Construye el filtro en base al historial del Builder.
	 * @return
	 * Un filtro con las mismas condiciones de filtro que el builder.
	 */
	public Filtro<Producto> build(){
		return this.filtroproducto;
	}
}
